home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / pcb-1.000 / pcb-1 / pcb-1.3 / mymem.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  11KB  |  417 lines

  1. /*
  2.  *                            COPYRIGHT
  3.  *
  4.  *  PCB, interactive printed circuit board design
  5.  *  Copyright (C) 1994,1995 Thomas Nau
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *  Contact addresses for paper mail and Email:
  22.  *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
  23.  *  Thomas.Nau@rz.uni-ulm.de
  24.  *
  25.  */
  26.  
  27. static    char    *rcsid = "$Header$";
  28.  
  29. /* memory management functions
  30.  */
  31.  
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <memory.h>
  35. #include <ctype.h>
  36. #include <sys/types.h>
  37.  
  38. #include "data.h"
  39. #include "global.h"
  40. #include "error.h"
  41. #include "mymem.h"
  42. #include "misc.h"
  43.  
  44. /* ---------------------------------------------------------------------------
  45.  * some local prototypes
  46.  */
  47. static    void    DSRealloc(DynamicStringTypePtr, size_t);
  48.  
  49. /* ---------------------------------------------------------------------------
  50.  * get next slot for a pin, allocates memory if necessary
  51.  */
  52. PinTypePtr GetPinMemory(ElementTypePtr Element)
  53. {
  54.     PinTypePtr pin = Element->Pin;
  55.  
  56.         /* realloc new memory if necessary and clear it */
  57.     if (Element->PinN >= Element->PinMax)
  58.     {
  59.         Element->PinMax += STEP_PIN;    
  60.         pin = MyRealloc(pin, Element->PinMax *sizeof(PinType),
  61.             "GetPinMemory()");
  62.         Element->Pin = pin;
  63.         memset(pin +Element->PinN, 0, STEP_PIN*sizeof(PinType));
  64.     }
  65.     return(pin +Element->PinN++);
  66. }
  67.  
  68. /* ---------------------------------------------------------------------------
  69.  * get next slot for a via, allocates memory if necessary
  70.  */
  71. PinTypePtr GetViaMemory(DataTypePtr Data)
  72. {
  73.     PinTypePtr via = Data->Via;
  74.  
  75.         /* realloc new memory if necessary and clear it */
  76.     if (Data->ViaN >= Data->ViaMax)
  77.     {
  78.         Data->ViaMax += STEP_VIA;  
  79.         via = MyRealloc(via, Data->ViaMax *sizeof(PinType),
  80.             "GetViaMemory()");
  81.         Data->Via = via;
  82.         memset(via +Data->ViaN, 0, STEP_VIA*sizeof(PinType));
  83.     }
  84.     return(via +Data->ViaN++);
  85. }
  86.  
  87. /* ---------------------------------------------------------------------------
  88.  * get next slot for a line, allocates memory if necessary
  89.  */
  90. LineTypePtr GetLineMemory(LayerTypePtr Layer)
  91. {
  92.     LineTypePtr    line = Layer->Line;
  93.  
  94.         /* realloc new memory if necessary and clear it */
  95.     if (Layer->LineN >= Layer->LineMax)
  96.     {
  97.         Layer->LineMax += STEP_LINE;    
  98.         line = MyRealloc(line, Layer->LineMax *sizeof(LineType),
  99.             "GetLineMemory()");
  100.         Layer->Line = line;
  101.         memset(line +Layer->LineN, 0, STEP_LINE*sizeof(LineType));
  102.     }
  103.     return(line +Layer->LineN++);
  104. }
  105.  
  106. /* ---------------------------------------------------------------------------
  107.  * get next slot for a text object, allocates memory if necessary
  108.  */
  109. TextTypePtr GetTextMemory(LayerTypePtr Layer)
  110. {
  111.     TextTypePtr        text = Layer->Text;
  112.  
  113.         /* realloc new memory if necessary and clear it */
  114.     if (Layer->TextN >= Layer->TextMax)
  115.     {
  116.         Layer->TextMax += STEP_TEXT;    
  117.         text = MyRealloc(text, Layer->TextMax *sizeof(TextType),
  118.             "GetTextMemory()");
  119.         Layer->Text = text;
  120.         memset(text +Layer->TextN, 0, STEP_TEXT*sizeof(TextType));
  121.     }
  122.     return(text +Layer->TextN++);
  123. }
  124.  
  125. /* ---------------------------------------------------------------------------
  126.  * get next slot for a polygon object, allocates memory if necessary
  127.  */
  128. PolygonTypePtr GetPolygonMemory(LayerTypePtr Layer)
  129. {
  130.     PolygonTypePtr    polygon = Layer->Polygon;
  131.  
  132.         /* realloc new memory if necessary and clear it */
  133.     if (Layer->PolygonN >= Layer->PolygonMax)
  134.     {
  135.         Layer->PolygonMax += STEP_POLYGON;    
  136.         polygon = MyRealloc(polygon, Layer->PolygonMax *sizeof(PolygonType),
  137.             "GetPolygonMemory()");
  138.         Layer->Polygon = polygon;
  139.         memset(polygon +Layer->PolygonN, 0, STEP_POLYGON *sizeof(PolygonType));
  140.     }
  141.     return(polygon +Layer->PolygonN++);
  142. }
  143.  
  144. /* ---------------------------------------------------------------------------
  145.  * gets the next slot for a point in a polygon struct, allocates memory
  146.  * if necessary
  147.  */
  148. PolygonPointTypePtr GetPointMemoryInPolygon(PolygonTypePtr Polygon)
  149. {
  150.     PolygonPointTypePtr    points = Polygon->Points;
  151.  
  152.         /* realloc new memory if necessary and clear it */
  153.     if (Polygon->PointN >= Polygon->PointMax)
  154.     {
  155.         Polygon->PointMax += STEP_POLYGONPOINT;    
  156.         points = MyRealloc(points, Polygon->PointMax *sizeof(PolygonPointType),
  157.             "GetPointMemoryInPolygon()");
  158.         Polygon->Points = points;
  159.         memset(points +Polygon->PointN, 0,
  160.             STEP_POLYGONPOINT *sizeof(PolygonPointType));
  161.     }
  162.     return(points +Polygon->PointN++);
  163. }
  164.  
  165. /* ---------------------------------------------------------------------------
  166.  * get next slot for an element, allocates memory if necessary
  167.  */
  168. ElementTypePtr GetElementMemory(DataTypePtr Data)
  169. {
  170.     ElementTypePtr element = Data->Element;
  171.  
  172.         /* realloc new memory if necessary and clear it */
  173.     if (Data->ElementN >= Data->ElementMax)
  174.     {
  175.         Data->ElementMax += STEP_ELEMENT;    
  176.         element = MyRealloc(element, Data->ElementMax *sizeof(ElementType),
  177.             "GetElementMemory()");
  178.         Data->Element = element;
  179.         memset(element +Data->ElementN, 0, STEP_ELEMENT*sizeof(ElementType));
  180.     }
  181.     return(element +Data->ElementN++);
  182. }
  183.  
  184. /* ---------------------------------------------------------------------------
  185.  * allocates memory with error handling
  186.  */
  187. void *MyCalloc(size_t Number, size_t Size, char *Text)
  188. {
  189.     void    *p;
  190.  
  191.     if ((p = calloc(Number, Size)) == NULL)
  192.         MyFatal("out of memory during calloc() in '%s'()\n",
  193.             (Text ? Text : "(unknown)"));
  194.     return(p);
  195. }
  196.  
  197. /* ---------------------------------------------------------------------------
  198.  * allocates memory with error handling
  199.  * this is a save version because BSD doesn't support the
  200.  * handling of NULL pointers in realoc()
  201.  */
  202. void *MyRealloc(void *Ptr, size_t Size, char *Text)
  203. {
  204.     void    *p;
  205.  
  206.     p = Ptr ? realloc(Ptr, Size) : malloc(Size);
  207.     if (!p)
  208.         MyFatal("out of memory during realloc() in '%s'()\n",
  209.             (Text ? Text : "(unknown)"));
  210.     return(p);
  211. }
  212.  
  213. /* ---------------------------------------------------------------------------
  214.  * allocates memory for a new string, does some error processing
  215.  */
  216. char *MyStrdup(char *S, char *Text)
  217. {
  218.     char    *p;
  219.  
  220.     if ((p = strdup(S)) == NULL)
  221.         MyFatal("out of memory during strdup() in '%s'\n",
  222.             (Text ? Text : "(unknown)"));
  223.     return(p);    
  224. }
  225.  
  226. /* ---------------------------------------------------------------------------
  227.  * frees memory and sets pointer to NULL
  228.  */
  229. void MyFree(char **Ptr)
  230. {
  231.     SaveFree(*Ptr);
  232.     *Ptr = NULL;
  233. }
  234.  
  235. /* ---------------------------------------------------------------------------
  236.  * frees memory used by a polygon
  237.  */
  238. void FreePolygonMemory(PolygonTypePtr Polygon)
  239. {
  240.     if (Polygon)
  241.     {
  242.         MyFree((char **) &Polygon->Points);
  243.         memset(Polygon, 0, sizeof(PolygonType));
  244.     }
  245. }
  246.  
  247. /* ---------------------------------------------------------------------------
  248.  * frees memory used by an element
  249.  */
  250. void FreeElementMemory(ElementTypePtr Element)
  251. {
  252.     if (Element)
  253.     {
  254.         MyFree(&CANONICAL_NAME(Element));
  255.         MyFree(&NAMEONPCB_NAME(Element));
  256.         PIN_LOOP(Element, MyFree(&pin->Name););
  257.         MyFree((char **) &Element->Pin);
  258.         MyFree((char **) &Element->Line);
  259.         MyFree((char **) &Element->Arc);
  260.         memset(Element, 0, sizeof(ElementType));
  261.     }
  262. }
  263.  
  264. /* ---------------------------------------------------------------------------
  265.  * free memory used by PCB
  266.  */
  267. void FreePCBMemory(PCBTypePtr PCBPtr)
  268. {
  269.     int        i;
  270.  
  271.     if (PCBPtr)
  272.     {
  273.             /* release pixmap and names */
  274.         ReleaseSaveUnderPixmap();
  275.         MyFree(&PCBPtr->Name);
  276.         MyFree(&PCBPtr->Filename);
  277.         FreeDataMemory(PCBPtr->Data);
  278.  
  279.             /* release font symbols */
  280.         for (i = 0; i <= MAX_FONTPOSITION; i++)
  281.             MyFree((char **) &PCBPtr->Font.Symbol[i].Line);
  282.  
  283.             /* clear struct */
  284.         memset(PCBPtr, 0, sizeof(PCBType));
  285.     }
  286. }
  287.  
  288. /* ---------------------------------------------------------------------------
  289.  * free memory used by data struct
  290.  */
  291. void FreeDataMemory(DataTypePtr Data)
  292. {
  293.     LayerTypePtr    layer;
  294.     int                i;
  295.  
  296.     if (Data)
  297.     {
  298.         VIA_LOOP(Data, MyFree(&via->Name););
  299.         ELEMENT_LOOP(Data, FreeElementMemory(element););
  300.  
  301.         for (layer = Data->Layer, i = 0; i < MAX_LAYER; layer++, i++)
  302.         {
  303.             TEXT_LOOP(layer, MyFree(&text->TextString););
  304.             MyFree(&layer->Name);
  305.             MyFree((char **) &layer->Line);
  306.             MyFree((char **) &layer->Text);
  307.             POLYGON_LOOP(layer, FreePolygonMemory(polygon));
  308.             MyFree((char **) &layer->Polygon);
  309.         }
  310.  
  311.             /* clear struct */
  312.         memset(Data, 0, sizeof(DataType));
  313.     }
  314. }
  315.  
  316. /* ---------------------------------------------------------------------------
  317.  * a 'save' free routine which first does a quick check if the pointer
  318.  * is zero. The routine isn't implemented as a macro to make additional
  319.  * savety features easier to implement
  320.  */
  321. void SaveFree(void *Ptr)
  322. {
  323.     if (Ptr)
  324.         free(Ptr);
  325. }
  326.  
  327. /* ---------------------------------------------------------------------------
  328.  * reallocates memory for a dynamic length string if necessary
  329.  */
  330. static void DSRealloc(DynamicStringTypePtr Ptr, size_t Length)
  331. {
  332.     if (Ptr->Data == NULL || Length >= Ptr->MaxLength)
  333.     {
  334.         Ptr->MaxLength = Length +512;
  335.         Ptr->Data = MyRealloc(Ptr->Data, Ptr->MaxLength, "ReallocDS()");
  336.     }
  337. }
  338.  
  339. /* ---------------------------------------------------------------------------
  340.  * adds one character to a dynamic string
  341.  */
  342. void DSAddCharacter(DynamicStringTypePtr Ptr, char Char)
  343. {
  344.     size_t    position = Ptr->Data ? strlen(Ptr->Data) : 0;
  345.  
  346.     DSRealloc(Ptr, position+1);
  347.     Ptr->Data[position++] = Char;
  348.     Ptr->Data[position] = '\0';
  349. }
  350.  
  351. /* ---------------------------------------------------------------------------
  352.  * add a string to a dynamic string
  353.  */
  354. void DSAddString(DynamicStringTypePtr Ptr, char *S)
  355. {
  356.     size_t    position = Ptr->Data ? strlen(Ptr->Data) : 0;
  357.  
  358.     DSRealloc(Ptr, position+1+strlen(S));
  359.     strcat(&Ptr->Data[position], S);
  360.  
  361. /* ----------------------------------------------------------------------
  362.  * clears a dynamic string
  363.  */
  364. void DSClearString(DynamicStringTypePtr Ptr)
  365. {
  366.     if (Ptr->Data)
  367.         Ptr->Data[0] = '\0';
  368. }
  369.  
  370. /* ---------------------------------------------------------------------------
  371.  * strips leading and trailing blanks from the passed string and
  372.  * returns a pointer to the new 'duped' one or NULL if the old one
  373.  * holds only white space characters
  374.  */
  375. char *StripWhiteSpaceAndDup(char *S)
  376. {
  377.     char    *p1, *p2;
  378.     size_t    length;
  379.  
  380.     if (!S || ! *S)
  381.         return(NULL);
  382.  
  383.         /* strip leading blanks */
  384.     for (p1 = S; *p1 && isspace(*p1); p1++);
  385.  
  386.         /* strip trailing blanksand get string length */
  387.     length = strlen(p1);
  388.     for (p2 = p1 +length -1; length && isspace(*p2); p2--, length--);
  389.  
  390.         /* string is not empty -> allocate memory */
  391.     if (length)
  392.     {
  393.         p2 = MyRealloc(NULL, length+1, "StripWhiteSpace()");
  394.         strncpy(p2, p1, length);
  395.         *(p2 +length) = '\0';
  396.         return(p2);
  397.     }
  398.     else
  399.         return(NULL);
  400. }
  401.  
  402. #ifdef NEED_STRDUP
  403. /* ---------------------------------------------------------------------------
  404.  * not all systems have strdup()
  405.  * mailed by Adrian Godwin (agodwin@acorn.co.uk) for Acorn RISCiX
  406.  */
  407. char *strdup(const char *S)
  408. {
  409.     char    *new;
  410.  
  411.     if ((new = malloc(strlen(S)+1)) != NULL)
  412.         strcpy(new, S);
  413.     return(new);
  414. }
  415. #endif
  416.